JULIA possède un système de type et de méthode qui lui confère une approche objet. La fonction typeof() renvoie le type d'une variable de base Int32, Float64... JULIA est conçu pour permettre facilement d'étendre l'environnement à de nouveaux type de variable.
Le types sont organisés suivant un hiérarchie comme on peut le voir sur l'arborescence partielle ci-dessous
(arborescence générée à l'aide de https://github.com/tanmaykm/julia_types/blob/master/julia_types.jl)
In [30]:
    
function f(x::Any)
    sin(x+1)
end
    
    Out[30]:
In [31]:
    
function f(n::Integer)
    n
end
    
    Out[31]:
In [32]:
    
f(3.0)
    
    Out[32]:
In [33]:
    
f(3)
    
    Out[33]:
In [34]:
    
f(im)
    
    Out[34]:
In [35]:
    
f(-2)
    
    Out[35]:
In [37]:
    
+
    
    Out[37]:
In [38]:
    
+(1,2)
    
    Out[38]:
In [15]:
    
f(sqrt(2))
    
    
In [58]:
    
abstract type Grid end # juste en dessous de Any
mutable struct Grid1d <: Grid
    debut::Float64
    fin::Float64
    n::Int32
end
    
    
In [40]:
    
a=Grid1d(0,1,2)
    
    Out[40]:
In [41]:
    
a.debut
    
    Out[41]:
In [42]:
    
a.fin
    
    Out[42]:
In [43]:
    
a.n
    
    Out[43]:
In [44]:
    
function Base.show(io::IO,g::Grid1d)
    print(io, "Grid 1d : début $(g.debut) , fin $(g.fin) , $(g.n) éléments\n")
end
    
In [45]:
    
Base.show(a)
    
    
In [47]:
    
println(a)
    
    
In [48]:
    
a
    
    Out[48]:
In [55]:
    
import Base:+
function +(g::Grid1d,n::Integer)
    g.n +=n
    return g
end
    
    Out[55]:
In [56]:
    
a=Grid1d(0,1,2)
    
    Out[56]:
In [57]:
    
a+2
    
    Out[57]:
In [60]:
    
a+=1
    
    Out[60]:
Attention l'addition n'est pas forcément commutative !
In [61]:
    
2+a
    
    
ni unaire !
In [63]:
    
-a
    
    
Notez le message d'erreur qui est très claire !
In [64]:
    
a+[1,2]
    
    
In [65]:
    
function Base.size(g::Grid)
    return g.n
end
    
In [66]:
    
size(a)
    
    Out[66]:
In [67]:
    
function Base.det(g::Grid1d)
    g.fin-g.debut
end
    
    
In [27]:
    
det(a)
    
    Out[27]:
In [28]:
    
abstract Grid # juste en dessous de Any
type Grid1d <: Grid
    debut::Float64
    fin::Float64
    n::Int32
    
    # constructeurs par défaut sans argument
    function Grid1d()
        new(0,0,0)
    end
    
    # constructeurs par défaut avec argument
    function Grid1d(a,b,c)
        if c<=0
            error("pas possible")
        else
            new(a,b,c)
        end
    end
end
    
    
In [29]:
    
b=Grid1d(0,1,-1)
    
    
Il devient possible de déterminer un constructeurs pour différentes entrées.
Il faut au préalable bien penser sa hiérarchie de type et écrire autant de fonctions constructeurs que de cas d'initialisation du nouveau type.
In [68]:
    
Base.start(a::Grid1d) = 1
function Base.next(a::Grid1d, state)
    if state == 1
        return (a.debut,2)
    else
        return (a.debut+(a.fin-a.debut)*(state-1)/a.n , state+1)
    end
end
Base.done(a::Grid1d, state) = state > a.n +1
    
    
In [31]:
    
a=Grid1d(0,1,10)
    
    Out[31]:
In [32]:
    
start(a)
    
    Out[32]:
In [33]:
    
next(a,0)
    
    Out[33]:
In [34]:
    
for i in a
    println(i)
end
    
    
Il devient possible de construire des itérateurs sur une grille 2d, 3d renvoyant les coordonnées des points de la grille... Mais on peut imaginer sur une triangulation etc...